BITS 16

%include "macrosmodoreal.mac"

%define TSS_0_DESC 0x20
%define TSS_1_DESC 0x28
%define TSS_2_DESC 0x30

%define SEG_VIDEO_DESC 0x18

global start
extern GDT_DESC
extern gdt
extern IDT_DESC
extern idtFill
extern tsss

;Aca arranca todo, en el primer byte.
start:
		cli					;no me interrumpan por ahora, estoy ocupado
		jmp 	bienvenida

;aca ponemos todos los mensajes		
iniciando: db 'Iniciando el kernel mas inutil del mundo'
iniciando_len equ $ - iniciando

nombre_grupo: db 'Thomas Fischer - Kevin Allekotte'
nombre_grupo_len equ $ - nombre_grupo

bienvenida:

	IMPRIMIR_MODO_REAL iniciando, iniciando_len, 0x07, 0, 0

	; Ejercicios AQUI

		; TODO: Habilitar A20

		call	disable_A20
		call	check_A20
		call 	enable_A20
		call	check_A20

		; TODO: Dehabilitar Interrupciones

		cli
		
	; Ejercicio 1
		
		; TODO: Cargar el registro GDTR

		lgdt [GDT_DESC]

		; TODO: Pasar a modo protegido (seteamos el bit PE del registro cr0)

		mov 	eax, cr0
		or  	eax, 01h
		mov 	cr0, eax

		; segundo segmento en la GDT (codigo kernel), el primero es nulo
		jmp		0x08:modo_protegido

BITS 32

modo_protegido:

		mov		ax, 0x10			; tercer segmento en la GDT (datos kernel)
		mov		ds, ax				; acomodo los segmentos antes de hacer lio
		mov		fs, ax				; acomodo los segmentos antes de hacer lio
		mov		gs, ax				; acomodo los segmentos antes de hacer lio
		mov		ss, ax				; acomodo los segmentos antes de hacer lio

		mov		ax, SEG_VIDEO_DESC
		mov		es, ax				; pongo en es el descriptor de memoria de video, porque lo usoi para escribir a la pantalla

		; limpio la pantalla

			;mov edi, 0xb8000
			xor edi, edi
			mov ecx, 80*25

			xor eax, eax
			mov ah, 0x00
			mov al, 0x0a

			for:
				mov [es:edi], ax
				inc edi
				inc edi
			loop for

		; dibujo un marco en pantalla

			xor edi, edi
			xor eax, eax
			mov ah, 0x0e			; attr = amarillo

			mov al, 201
			mov [es:edi], ax
			inc edi
			inc edi

			mov al, 205
			mov ecx, 78
			for2:
				mov [es:edi], ax
				inc edi
				inc edi
			loop for2

			mov al, 187
			mov [es:edi], ax
			inc edi
			inc edi

			mov al, 186
			mov ecx, 23
			for3:
				mov [es:edi], ax
				add edi, 2*79
				mov [es:edi], ax
				inc edi
				inc edi
			loop for3

			mov al, 200
			mov [es:edi], ax
			inc edi
			inc edi

			mov ecx, 78
			mov al, 205
			for4:
				mov [es:edi], ax
				inc edi
				inc edi
			loop for4

			mov al, 188
			mov [es:edi], ax
			inc edi
			inc edi

	; Ejercicio 2

		; TODO: Habilitar paginacion

		mov		eax, page_table_kernel_0
		or		eax, 0x3					;supervisor, read/write, present
		mov		[page_dir_kernel], eax

		mov		eax, page_table_pintor_0
		or		eax, 0x3					;supervisor, read/write, present
		mov		[page_dir_pintor], eax

		mov		eax, page_dir_kernel		;cargo la direccion del directorio en cr3
		mov		cr3, eax
		
		mov		eax, cr0				
		or		eax, 0x80000000				;habilito paginacion
		mov		cr0, eax

		; Escribo el nombre del grupo en pantalla

		mov esi, nombre_grupo
		xor edi, edi
		add edi, 2*(80+1)			; (2,2)
		mov ah, 0x06				; attr = marron

		mov ecx, nombre_grupo_len

		escribir:
			mov al, [esi]
			mov [es:edi], ax
			inc edi
			inc edi
			inc esi
		loop escribir

	; Ejercicio 3

		; TODO: Inicializar la IDT

			call idtFill
		
		; TODO: Resetear la pic
		; remapeo de las interrupciones de los controladores de interrupcion,
		; porque se pisan con las interrupciones del procesador

			; Inicializacion PIC1

			mov al, 0x11		; ICW1: IRQs activas por flanco, Modo cascada, ICW4 Si.
			out 0x20, al
			mov al, 0x20 		; ICW2: INT base para el PIC1 Tipo 8. !!! 0x20 decia 8
			out 0x21, al
			mov al, 0x04		; ICW3: PIC1 Master, tiene un Slave conectado a IRQ2
			out 0x21 ,al
			mov al, 0x01		; ICW4: Modo No Buffered, Fin de Interrupcion Normal
			out 0x21, al		; Deshabilitamos las Interrupciones del PIC1
			mov al, 0xFF		; OCW1: Set o Clear el IMR
			out 0x21, al

			; Inicializacion PIC2

			mov al, 0x11		; ICW1: IRQs activas por flanco, Modo cascada, ICW4 Si.
			out 0xA0, al
			mov al, 0x28		; ICW2: INT base para el PIC1 Tipo 070h. !!! 0x28 decia 0x70
			out 0xA1, al
			mov al, 0x02		; ICW3: PIC2 Slave, IRQ2 es la linea que envia al Master
			out 0xA1, al
			mov al, 0x01		; ICW4: Modo No Buffered, Fin de Interrupcion Normal
			out 0xA1, al

		; TODO: Cargar el registro IDTR

			lidt [IDT_DESC]

	; Ejercicio 4

		; TODO: Inicializar las TSS

				; tss: 104 Bytes
				mov edi, tsss

			; TSS TASK 1 (PINTOR)

				add edi, 104

				mov dword [edi+28], page_dir_pintor	; directorio de paginas
				mov dword [edi+32], pintor			; eip (entry point)
				mov dword [edi+36], 0x0202			; eflags (interrupciones habilitadas)
				mov dword [edi+56], 0x16000			; esp
				mov dword [edi+60], 0x16000			; ebp
				mov [edi+72], es
				mov [edi+76], cs
				mov [edi+80], ss
				mov [edi+84], ds
				mov [edi+88], fs
				mov [edi+92], gs

			; TSS TASK 2 (TRADUCTOR)

				add edi, 104

				mov dword [edi+28], page_dir_kernel	; directorio de paginas
				mov dword [edi+32], traductor		; eip (entry point)
				mov dword [edi+36], 0x0202			; eflags (interrupciones habilitadas)
				mov dword [edi+56], 0x17000			; esp
				mov dword [edi+60], 0x17000			; ebp
				mov [edi+72], es
				mov [edi+76], cs
				mov [edi+80], ss
				mov [edi+84], ds
				mov [edi+88], fs
				mov [edi+92], gs

		; TODO: Inicializar correctamente los descriptores de TSS en la GDT

			; Descriptor TSS 0

				mov edi, gdt
				add edi, TSS_0_DESC

				mov eax, tsss

				mov [edi+2], ax
				shr eax, 16
				mov [edi+4], al
				mov [edi+7], ah

			; Descriptor TSS 1

				mov edi, gdt
				add edi, TSS_1_DESC

				mov eax, tsss
				add eax, 104

				mov [edi+2], ax
				shr eax, 16
				mov [edi+4], al
				mov [edi+7], ah

			; Descriptor TSS 2

				mov edi, gdt
				add edi, TSS_2_DESC

				mov eax, tsss
				add eax, 208

				mov [edi+2], ax
				shr eax, 16
				mov [edi+4], al
				mov [edi+7], ah

		; TODO: Cargar el registro TR con el descriptor de la GDT de la TSS actual (nil)

			mov ax, TSS_0_DESC
			ltr ax

		; TODO: Habilitar el PIC1

			mov al,0x00
			out 0x21, al

		; Dejo deshabilitado el PIC2

			mov al,0xFF
			out 0xA1, al

		; TODO: Habilitar Interrupciones

			sti
		
		; TODO: Saltar a la primer tarea

			jmp TSS_1_DESC:0

%include "a20.asm"

%define TASK1INIT 0x8000
%define TASK2INIT 0x9000
%define KORG 0x1200

TIMES TASK1INIT - KORG - ($ - $$) db 0x00
pintor:
	incbin "pintor.tsk"

TIMES TASK2INIT - KORG - ($ - $$) db 0x00
traductor:
	incbin "traductor.tsk"

%include "paging.asm"
